﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml;

namespace ShadowHelper
{
    public partial class SourceForm : Form
    {
        private String enterText = "";
        private String leaveText = "";
        private List<Source> sources;
        private List<String> removedIds;
        private List<String> modifiedIds;
        private List<int> modifiedIndexes;
        private List<String> addedIds;
        private List<int> addedIndexes;

        public SourceForm()
        {
            InitializeComponent();
            sources = new List<Source>();
            removedIds = new List<String>();
            modifiedIndexes = new List<int>();
            modifiedIds = new List<String>();
            addedIndexes = new List<int>();
            addedIds = new List<String>();
        }

        private void SourceForm_Load(object sender, EventArgs e)
        {
            sources.AddRange(Program.form1.Sources);
            if (sources.Count != 0)
            {
                foreach (Source src in sources)
                {
                    sourceList.Items.Add(src.Name);
                }
                sourceList.SelectedIndex = Program.form1.cbSource.SelectedIndex;
            }
            else
            {
                btnRemove.Enabled = false;
            }
        }

        private void sourceList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (sourceList.SelectedIndex != -1)
            {
                tbName.Text = sources[sourceList.SelectedIndex].Name;
                tbURL.Text = sources[sourceList.SelectedIndex].Url;
            }
            else
            {
                tbName.Text = "";
                tbURL.Text = "";
            }
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            Source source = new Source
            {
                Id = GuidTo16String(),// Guid.NewGuid().ToString(),
                Name = "New",
                Url = "http://",
                Accounts = new List<String>()
            };
            sourceList.Items.Add(source.Name);
            tbName.Text = source.Name;
            tbURL.Text = source.Url;
            sources.Add(source);
            addedIds.Add(source.Id);
            addedIndexes.Add(sources.Count - 1);
            sourceList.SelectedIndex = sources.Count - 1;
            if (!btnRemove.Enabled)
            {
                btnRemove.Enabled = true;
            }
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            String sourceId = sources[sourceList.SelectedIndex].Id;
            int i = 0, j = 0;
            modifiedIndexes.Sort();
            addedIndexes.Sort();
            if (modifiedIds.Contains(sourceId))
            {
                i = modifiedIndexes.IndexOf(sourceList.SelectedIndex);
                modifiedIds.Remove(sourceId);
                modifiedIndexes.Remove(sourceList.SelectedIndex);
                for (; i < modifiedIndexes.Count; i++)
                {
                    modifiedIndexes[i]--;
                }
            }
            if (addedIds.Contains(sourceId))
            {
                j = addedIndexes.IndexOf(sourceList.SelectedIndex);
                addedIds.Remove(sourceId);
                addedIndexes.Remove(sourceList.SelectedIndex);
                for (; j < addedIndexes.Count; j++ )
                {
                    addedIndexes[j]--;
                }
            }
            else
            {
                removedIds.Add(sourceId);
            }

            if (i == 0)
            {
                modifiedIndexes.Add(sourceList.SelectedIndex);
                modifiedIndexes.Sort();
                i = modifiedIndexes.IndexOf(sourceList.SelectedIndex);
                modifiedIndexes.Remove(sourceList.SelectedIndex);
                for (; i < modifiedIndexes.Count; i++)
                {
                    modifiedIndexes[i]--;
                }
            }

            if (j == 0)
            {
                addedIndexes.Add(sourceList.SelectedIndex);
                addedIndexes.Sort();
                i = addedIndexes.IndexOf(sourceList.SelectedIndex);
                addedIndexes.Remove(sourceList.SelectedIndex);
                for (; j < addedIndexes.Count; j++)
                {
                    addedIndexes[j]--;
                }
            }

            sources.RemoveAt(sourceList.SelectedIndex);
            sourceList.Items.RemoveAt(sourceList.SelectedIndex--);
            if (sourceList.SelectedIndex == -1 && sourceList.Items.Count > 0)
            {
                sourceList.SelectedIndex = 0;
            }
            else if (sourceList.Items.Count == 0)
            {
                btnRemove.Enabled = false;
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("config.xml");
            XmlNode rootNode = xmlDoc.SelectSingleNode("Config");
            if (removedIds.Count > 0)
            {
                foreach (String id in removedIds)
                {
                    XmlNode detNode = rootNode.SelectSingleNode("source[@id='" + id + "']");
                    rootNode.RemoveChild(detNode);
                }
            }

            if (modifiedIndexes.Count > 0)
            {
                foreach (int index in modifiedIndexes)
                {
                    XmlNode oldNode = rootNode.SelectSingleNode("source[@id='" + sources[index].Id + "']");
                    oldNode.Attributes["id"].Value = sources[index].Id;
                    oldNode.Attributes["name"].Value = sources[index].Name;
                    oldNode.Attributes["url"].Value = sources[index].Url;
                }
            }

            if (addedIndexes.Count > 0)
            {
                foreach (int index in addedIndexes)
                {
                    XmlElement element = xmlDoc.CreateElement("source");
                    element.SetAttribute("id", sources[index].Id);
                    element.SetAttribute("name", sources[index].Name);
                    element.SetAttribute("url", sources[index].Url);
                    rootNode.AppendChild(element);
                }
            }

            rootNode.Attributes["usedIndex"].Value = sourceList.SelectedIndex.ToString();

            xmlDoc.Save("config.xml");
            Program.form1.Sources.Clear();
            Program.form1.Sources.AddRange(sources);
            Program.form1.cbSource.Items.Clear();
            foreach (Source src in sources)
            {
                Program.form1.cbSource.Items.Add(src.Name);
            }
            if (sourceList.SelectedIndex >= 0)
            {
                Program.form1.cbSource.SelectedIndex = sourceList.SelectedIndex;
                Program.form1.btnUpdate.Enabled = true;
                Program.form1.cbSource_SelectedIndexChanged(this, null);
            }
            else
            {
                Program.form1.cbSource.Text = "None";
                Program.form1.cbAccount.Items.Clear();
                Program.form1.cbAccount.Text = "None";
                Program.form1.btnOK.Enabled = false;
                Program.form1.btnUpdate.Enabled = false;
            }
            Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void tbName_Enter(object sender, EventArgs e)
        {
            enterText = tbName.Text;
        }

        private void tbName_Leave(object sender, EventArgs e)
        {
            leaveText = tbName.Text;
            if (enterText != leaveText)
            {
                sources[sourceList.SelectedIndex].Name = tbName.Text;
                sourceList.Items[sourceList.SelectedIndex] = tbName.Text;
                String id = sources[sourceList.SelectedIndex].Id;
                if (!addedIds.Contains(id) && !modifiedIds.Contains(id))
                {
                    modifiedIds.Add(id);
                    modifiedIndexes.Add(sourceList.SelectedIndex);
                }
            }
            enterText = "";
            leaveText = "";
        }

        private void tbURL_Enter(object sender, EventArgs e)
        {
            enterText = tbURL.Text;
        }

        private void tbURL_Leave(object sender, EventArgs e)
        {
            leaveText = tbURL.Text;
            if (enterText != leaveText)
            {
                sources[sourceList.SelectedIndex].Url = leaveText;
                String id = sources[sourceList.SelectedIndex].Id;
                if (!addedIds.Contains(id) && !modifiedIds.Contains(id))
                {
                    modifiedIds.Add(id);
                    modifiedIndexes.Add(sourceList.SelectedIndex);
                }
            }
            enterText = "";
            leaveText = "";
        }

        public static String GuidTo16String()
        {
            long i = 1;
            foreach (byte b in Guid.NewGuid().ToByteArray())
                i *= ((int)b + 1);
            return string.Format("{0:x}", i - DateTime.Now.Ticks);
        }
    }
}
